home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-01-28 | 14.0 KB | 451 lines | [TEXT/MPCC] |
- // fastmap.cpp
-
- // lots of fun assumtions ;-j
-
- #include <stdio.h>
- #include <stdlib.h>
- #include "error.h"
-
- //#include "Utilities.h"
- #include "fastmap.h"
-
- extern GWorldPtr boff;
-
- // gworld must have bits locked
- Fastmap::Fastmap( GWorldPtr gw, Boolean isMasked, short index, short hsize, short vsize )
- {
- PixMapHandle pmh = GetGWorldPixMap(gw); verify(pmh);
- long *src, *dst;
- src = (long *) GetPixBaseAddr(pmh); verify(src);
- StripAddress(src);
-
- masked = isMasked;
-
- width = hsize;
- if (width & 3) Debugger();
- if (width == 0) {
- width = (**pmh).bounds.right;
- if (width & 3) Debugger();
- if (masked)
- width /= 2;
- }
-
- height = (**pmh).bounds.bottom;
- if (vsize)
- height = vsize;
-
- long dataSize = (long) height * width;
- if (masked)
- dataSize *= 2; // need room for mask, which is mixed in
- bits = (long *) NewPtr(dataSize); verify(bits);
-
- // now we copy the picture from the gworld to our memory
- long srcrb, soffset, loopoffset;
- int rowlongs, loop;
- long startx, endx;
-
- dst = bits;
-
- srcrb = (**pmh).rowBytes & 0x3fff;
- startx = index * width;
- endx = startx + width;
-
- // set up offsets
- soffset = startx;
- src = (long *) ((long) src + soffset);
- rowlongs = (endx - startx) >> 2;
-
- // prepare for loop
- loop = height;
- loopoffset = srcrb - (rowlongs << 2);
-
- // copy the pix
- short nnn;
-
- if (!masked)
- while (loop-- > 0) {
- for (nnn = 0; nnn < rowlongs; nnn++)
- *dst++ = *src++;
- // dst = (long *) (((long) dst) + loopoffset);
- src = (long *) (((long) src) + loopoffset);
- }
- else {
- long val, msk;
- while (loop-- > 0) {
- for (nnn = 0; nnn < rowlongs; nnn++) {
- val = *src++;
- // we make mask ourselves -- all whitespace is not mask
- msk = 0;
- if ((val & 0xFF000000) == 0) msk = 0xFF000000;
- if ((val & 0x00FF0000) == 0) msk |= 0x00FF0000;
- if ((val & 0x0000FF00) == 0) msk |= 0x0000FF00;
- if ((val & 0x000000FF) == 0) msk |= 0x000000FF;
- val |= msk; // change those zeroes to FF's
- msk = msk ^ 0xFFFFFFFF; // flip mask, chump
- *dst++ = val;
- *dst++ = msk;
- }
- src = (long *) ((long) src + loopoffset);
- }
- }
- }
-
- void
- Fastmap::Draw8by8Mask(GWorldPtr destworld, Rect *r)
- {
- PixMapPtr dstpm;
- long *src, *dst, dest;
- long dstrb, dstrbm4;
- short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
-
- if (r->left < 0 || r->top < 0 || r->right > winwidth || r->bottom > winheight)
- return; // avoid writing over someone else's memory
-
- src = bits;
-
- dstpm = *destworld->portPixMap;
- dest = (long) dstpm->baseAddr;
- dstrb = dstpm->rowBytes & 0x3fff;
- dstrbm4 = dstrb - 4;
- dest += r->left;
- dest += r->top * dstrb;
- dst = (long *) dest;
-
- // copy the pix
- short nnn = height;
- long tmp, msk, val;
- while (nnn--) {
- val = *src++;
- tmp = *dst;
- msk = *src++;
- tmp |= msk;
- tmp &= val;
- *dst++ = tmp;
-
- val = *src++;
- tmp = *dst;
- msk = *src++;
- tmp |= msk;
- tmp &= val;
- *dst = tmp;
-
- dst = (long *) ((long) dst + dstrbm4);
- }
- }
-
- void
- Fastmap::DrawMask(GWorldPtr destworld, Rect *r)
- {
- // PixMapPtr dstpm;
- PixMapHandle pmh = GetGWorldPixMap(destworld);
- register long *src, *dst;
- long dest;
- long dstrb;
- short loop, copyLongs, srcDelta, leftStub;
- short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
-
- if (r->right < 0 || r->bottom < 0 || r->left >= winwidth || r->top >= winheight)
- return; // avoid writing over someone else's memory
-
- verify(r->right - r->left == width && r->bottom - r->top == height);
-
- src = bits;
-
- dest = (long) GetPixBaseAddr(pmh); verify(dest); StripAddress((void *) dest);
- dstrb = (**pmh).rowBytes & 0x3fff;
- dest += r->left;
- dest += r->top * dstrb;
- dst = (long *) dest;
-
- loop = height;
- copyLongs = width >> 2;
- srcDelta = 0;
- if (r->top < 0) { // runs off top of screen
- short offs = -(r->top);
- src = (long *) ((long) src + ((offs * width) << 1)); // offset source
- dst = (long *) ((long) dst + offs * dstrb); // offset dest
- loop -= offs;
- }
- if (r->bottom > winheight) { // runs off bottom of screen
- loop -= r->bottom - winheight;
- }
- if (r->left < 0) { // runs off top of screen
- short offs = -(r->left);
- // square up
- leftStub = offs & 3;
- if (leftStub) offs += (4 - leftStub);
- offs -= 4; // somehow this doesn't crash it
-
- src = (long *) ((long) src + (offs << 1)); // offset source
- dst = (long *) ((long) dst + offs); // offset dest
-
- copyLongs -= offs >> 2;
- srcDelta += offs;
- }
- if (r->right > winwidth) { // runs off right of screen
- // we're going to let it run over for now, assume gworld has more rowbytes than should
- short offs = r->right - winwidth;
- // square up
- offs -= offs & 3;
-
- copyLongs -= offs >> 2;
- srcDelta += offs;
- }
-
- if (copyLongs <= 0) return; // nuttin' to copy
-
- // copy the pix
- register long tmp, msk, val;
- long dstDelta;
- dstDelta = dstrb - (copyLongs << 2);
- srcDelta <<= 1;
-
- /* if (leftStub) {
- // okay, we have to patch up the left column
- // this sux, but we only rarely have to do it, and it shouldn't be too slow
- // this will eventually be made moot
- short myLoop = loop;
- long *oldDest = dst, *oldSrc = src;
-
-
-
- while (loop--) {
- val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- dst = (long *) ((long) dst + dstDelta);
- src = (long *) ((long) src + srcDelta);
- }
-
- dst = oldDest; src = oldSrc;
- }*/
-
- while (loop--) {
- switch (copyLongs) {
- case 24: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 23: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 22: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 21: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 20: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 19: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 18: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 17: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 16: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 15: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 14: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 13: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 12: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 11: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 10: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 9: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 8: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 7: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 6: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 5: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 4: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 3: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 2: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 1: val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
- case 0: break;
- // default: DebugPrint(srcRect->right - srcRect->left); verify(false);
- }
- dst = (long *) ((long) dst + dstDelta);
- src = (long *) ((long) src + srcDelta);
- }
- }
-
-
- void
- Fastmap::Draw(GWorldPtr destworld, Rect *r)
- {
- PixMapPtr dstpm;
- PixMapHandle pmh = destworld->portPixMap;
- register long *src, *dst;
- long dest;
- long dstrb;
- short loop, copyLongs, srcDelta, leftStub;
- short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
-
- if (r->right < 0 || r->bottom < 0 || r->left >= winwidth || r->top >= winheight)
- return; // avoid writing over someone else's memory
-
- verify(r->right - r->left == width && r->bottom - r->top == height);
-
- src = bits;
-
- dstpm = *destworld->portPixMap;
- dest = (long) GetPixBaseAddr(pmh); verify(dest); StripAddress((void *) dest);
- dstrb = dstpm->rowBytes & 0x3fff;
- dest += r->left;
- dest += r->top * dstrb;
- dst = (long *) dest;
-
- loop = height;
- copyLongs = width >> 2;
- srcDelta = 0;
- if (r->top < 0) { // runs off top of screen
- short offs = -(r->top);
- src = (long *) ((long) src + ((offs * width) << 1)); // offset source
- dst = (long *) ((long) dst + offs * dstrb); // offset dest
- loop -= offs;
- }
- if (r->bottom > winheight) { // runs off bottom of screen
- loop -= r->bottom - winheight;
- }
- if (r->left < 0) { // runs off top of screen
- short offs = -(r->left);
- // square up
- leftStub = offs & 3;
- if (leftStub) offs += (4 - leftStub);
- offs -= 4; // somehow this doesn't crash it
-
- src = (long *) ((long) src + (offs << 1)); // offset source
- dst = (long *) ((long) dst + offs); // offset dest
-
- copyLongs -= offs >> 2;
- srcDelta += offs;
- }
- if (r->right > winwidth) { // runs off right of screen
- // we're going to let it run over for now, assume gworld has more rowbytes than should
- short offs = r->right - winwidth;
- // square up
- offs -= offs & 3;
-
- copyLongs -= offs >> 2;
- srcDelta += offs;
- }
-
- if (copyLongs <= 0) return; // nuttin' to copy
-
- // copy the pix
- long dstDelta;
- dstDelta = dstrb - (copyLongs << 2);
- srcDelta <<= 1;
-
- while (loop--) {
- switch (copyLongs) {
- case 24: *dst++ = *src++;
- case 23: *dst++ = *src++;
- case 22: *dst++ = *src++;
- case 21: *dst++ = *src++;
- case 20: *dst++ = *src++;
- case 19: *dst++ = *src++;
- case 18: *dst++ = *src++;
- case 17: *dst++ = *src++;
- case 16: *dst++ = *src++;
- case 15: *dst++ = *src++;
- case 14: *dst++ = *src++;
- case 13: *dst++ = *src++;
- case 12: *dst++ = *src++;
- case 11: *dst++ = *src++;
- case 10: *dst++ = *src++;
- case 9: *dst++ = *src++;
- case 8: *dst++ = *src++;
- case 7: *dst++ = *src++;
- case 6: *dst++ = *src++;
- case 5: *dst++ = *src++;
- case 4: *dst++ = *src++;
- case 3: *dst++ = *src++;
- case 2: *dst++ = *src++;
- case 1: *dst++ = *src++;
- case 0: break;
- // default: DebugPrint(srcRect->right - srcRect->left); verify(false);
- }
- dst = (long *) ((long) dst + dstDelta);
- src = (long *) ((long) src + srcDelta);
- }
- }
-
- void
- Fastmap::Draw8by8(GWorldPtr destworld, Rect *r)
- {
- if (masked) {
- Draw8by8Mask(destworld, r);
- return;
- }
-
- PixMapPtr dstpm;
- PixMapHandle pmh;
- long *src, *dst, dest;
- long dstrb, dstrbm4;
- short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
-
- if (r->left < 0 || r->top < 0 || r->right > winwidth || r->bottom > winheight)
- return; // avoid writing over someone else's memory
-
- src = bits;
-
- dstpm = *destworld->portPixMap;
- dest = (long) dstpm->baseAddr;
- dstrb = dstpm->rowBytes & 0x3fff;
- dstrbm4 = dstrb - 4;
- dest += r->left;
- dest += r->top * dstrb;
- dst = (long *) dest;
-
- // copy the pix
- *dst++ = *src++; *dst = *src++;
- dst = (long *) ((long) dst + dstrbm4);
- *dst++ = *src++; *dst = *src++;
- dst = (long *) ((long) dst + dstrbm4);
- *dst++ = *src++; *dst = *src++;
- dst = (long *) ((long) dst + dstrbm4);
- *dst++ = *src++; *dst = *src++;
- dst = (long *) ((long) dst + dstrbm4);
- *dst++ = *src++; *dst = *src++;
- dst = (long *) ((long) dst + dstrbm4);
- *dst++ = *src++; *dst = *src++;
- dst = (long *) ((long) dst + dstrbm4);
- *dst++ = *src++; *dst = *src++;
- dst = (long *) ((long) dst + dstrbm4);
- *dst++ = *src++; *dst = *src;
- }
-
- //extern GDHandle maindev;
- //extern WindowPtr myWindow;
-
-
- void LoadFastmaps(short baseID, short num, frameData *frameCounts, Rect *blockrect, Fastmap **bpix, short maxFrames)
- {
- short nnn;
- Rect r;
- PicHandle p;
-
- verify(bpix);
- verify(boff);
- SetGWorld(boff, nil); // our scratch space
-
- for (nnn = 0; nnn < num; nnn++) {
- p = GetPicture(nnn + baseID);
- if (!p)
- verify(false); // forget this one
-
- r = (**p).picFrame;
- OffsetRect(&r, -r.left, -r.top);
- verify(frameCounts[nnn].frames);
- verify(r.right % frameCounts[nnn].frames == 0); // reasonably safe check of frames
- blockrect[nnn] = r;
- blockrect[nnn].right /= frameCounts[nnn].frames;
- verify((blockrect[nnn].right & 3) == 0); // must be long-aligned
-
- // paint the picture into scratch
- EraseRect(&r);
- DrawPicture(p, &r);
- ReleaseResource((Handle) p);
-
-
- /*
- verify(myWindow);
- SetGWorld((GWorldPtr) myWindow, maindev);
- CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(((CWindowPtr) myWindow)->portPixMap),
- &r, &r, srcCopy, nil);
- SetGWorld(boff, nil);
- Debugger();
- */
-
- for (short mmm = 0; mmm < frameCounts[nnn].frames; mmm++) {
- // make fast map and copy pic in
- bpix[nnn*maxFrames+mmm] = new Fastmap(boff, frameCounts[nnn].masked,
- mmm, blockrect[nnn].right, blockrect[nnn].bottom);
- verify(bpix[nnn*maxFrames+mmm]);
- }
- }
- }